<style scoped>
.address_list{padding: 0 12px;}
.address_list>*{margin-bottom: 10px;}
.input-select_address{width: 100%;text-align: initial;}
.address_row{ background: var(--van-cell-background);border-radius: 8px;}
.address_row>.max{padding-left: 6px;}
.address_row .big{font-size: 1.1em;font-weight: bold;margin-bottom: 2px;}
.address_row .van-icon{font-size: 1.3em;}

.address_list_title{font-size: 18px;font-weight: bold;padding: 10px 0;text-align: center;position: relative;}
.address_list_title>.link{position: absolute;top: 10px;right: 10px;}
.address_list{overflow: hidden auto;max-height: 50vh;}
</style>
<template>
  <van-field v-bind="$attrs"
             label-align="top"
             readonly  >
    <template #input>
      <div class="input-select_address">
        <input v-if="!is_info" type="hidden" :name="name" :value="modelValue">
        <van-tabs v-if="!is_info && options.length>1" v-model:active="tab" @click-tab="change_type($event.name)">
          <van-tab v-for="row in options" :name="row.value" :title="row.content"></van-tab>
        </van-tabs>
        <div class="flex address_row" @click="show_select">
          <van-icon name="location" v-show="!is_info" />
          <div class="max">
            <div class="flex big" style="justify-content: space-between">
              <p>{{ show_address.name }} {{ show_address.phone }}</p>
              <van-tag v-if="is_info && type_title" size="medium" type="primary">{{ type_title }}</van-tag>
            </div>
            <div v-if="show_address.address" class="info">{{show_address.area_name}} {{show_address.address}}</div>
            <div v-else-if="!is_info" class="info">请选择地址</div>
          </div>
          <van-icon name="arrow" v-show="!is_info" />
        </div>

        <van-popup v-model:show="show_address_list" safe-area-inset-bottom round position="bottom" teleport="body">
          <div class="address_list_title max">
            <b>选择地址</b>
            <van-tag class="link" type="primary" size="large" v-show="address_type==='0'" @click="to_address">地址管理</van-tag>
          </div>
          <div class="address_list">
            <div class="flex address_row" v-for="row in (address_list_map[address_type] || [])">
              <div class="max" @click="change_address(row)">
                <div class="flex big" style="justify-content: space-between">
                  <p>{{ row.name }} {{ row.phone }}</p>
                  <van-tag v-if="row.default==1" type="primary">默认</van-tag>
                </div>
                <div class="info">{{row.area_name}} {{row.address}}</div>
              </div>
            </div>
            <van-empty v-show="Object.values(address_list).length===0" description="暂无地址可供选择" />
          </div>
        </van-popup>
      </div>
    </template>
  </van-field>


</template>

<script>
import s94 from "s94-js";
import {decode_config} from "@/js/s94_tool.js";
import {ajax} from "@/js/api_tool.js";
import {href_handle} from "@/vue_plugin/router_auto.js";

export default {
  name: "select_address",
  props: {
    name: String,
    modelValue: String,
    config: [String,Object],
    placeholder: String,
    is_info: Boolean,
  },
  emits: ['update:modelValue','change'],
  data(){
    return {
      need_display: true, //定义当modelValue变动时是否需要渲染，用来阻止当前组件变动 modelValue 后重新渲染
      options: [], // {content, value, address_list}
      tab: '',
      address_type: '',

      address_list_map: null,

      value_map: {},

      address_list: [],
      value: {},

      show_address_list: false,
      address_list_type: '',
    }
  },
  methods: {
    is_address(v){
      v = typeof v === 'undefined' ? this.modelValue : v;
      if (!v) return false;
      if (typeof v === 'string'){
        try { v = JSON.parse(v); } catch (e) { v={} }
      }
      if (!v || typeof v !== 'object') return false;
      return v.name && v.phone && v.address && s94.to_string(v.type) ? v : false;
    },
    display_value(){
      let address = this.is_address();
      if (!address) return;
      this.value_map[address.type] = address;
      this.tab = this.address_type = s94.to_string(address.type);
    },
    display_config(){
      this.options = decode_config(this.config || ["快递", "自提"]);
    },
    display_address_list(){
      if (this.address_list_map) return;
      ajax('/home/address/list', (res)=>{
        let list_map = {};
        Object.values(res.data).forEach(v=>{
          if (!list_map[v.type]){
            list_map[v.type] = [];
            if (!this.value_map[v.type]) this.value_map[v.type] = v; //设定类型的第一个地址为对应的值
          }
          list_map[v.type].push(v);
        })
        this.address_list_map = list_map;
        // 编辑模式下，没有 address_type 时，设定第一个为默认值
        if (!this.is_info && !this.address_type){
          this.change_type(this.options[0]["value"]);
        }
      })
    },
    init(){
      this.display_value();
      this.display_config();

      if (!this.is_info) this.display_address_list();
    },
    show_select(){
      if (this.is_info) return;
      this.display_address_list();
      this.show_address_list=true;
    },
    change_type(type){
      if (type === this.address_type) return;
      this.address_type = type;
      let address = this.value_map[type];
      this.change_address(address);
    },
    change_address(address){
      let keys = ["name","phone","address","area_id","area_name","type"];
      let val = {};
      if (this.is_address(address)){
        Object.keys(address).forEach(k=>{
          if (~keys.indexOf(k)) val[k] = address[k];
        })
        val = JSON.stringify(val);
      }else {
        val = '';
      }
      if (this.modelValue === s94.to_string(val)) return;
      this.need_display = false;
      setTimeout(()=>{this.need_display=true},10)
      this.$emit('update:modelValue', val);
      this.$emit('change', val);
    },
    to_address(){
      href_handle('/user/address');
    },
  },
  watch: {
    config(v){
      this.display_config();
    },
    modelValue(v){
      if (!this.need_display) return;
      this.display_value();
    },
  },
  computed: {
    show_address(){
      return this.is_address() || {};
    },
    type_title(){
      let type = s94.to_string(this.show_address.type);
      let res = "";
      this.options.forEach(row=>{
        if (row.value === type) res = row.content;
      })
      return res;
    }
  },
  mounted() {
    this.init();
  }
}
</script>